package dominio.investigacion

import dominio.individuos.Villano
import dominio.ubicaciones.Pais
import java.util.ArrayList
import java.util.List
import org.uqbar.commons.utils.Observable
import utilidades.Utils
import com.fasterxml.jackson.annotation.JsonIgnore
import org.eclipse.xtend.lib.annotations.Accessors

@Accessors
@Observable
class Caso {
	
	String nombre
	Villano responsable
	@JsonIgnore	List<Pais> rutaDeEscape
	String reporte
	String objetoRobado
	Pais paisDelRobo
	@JsonIgnore	private Mapamundi mapamundi
	Expedientes expedientes
	extension Utils utils = new Utils
	

	new() {
		this.rutaDeEscape = new ArrayList<Pais>
	}
	
	new(String nombreDelCaso, String reporte, String objetoRobado, Mapamundi mapamundi, Expedientes expedientes) {		
		this.nombre = nombreDelCaso
		this.rutaDeEscape = new ArrayList<Pais>
		this.reporte = reporte
		this.objetoRobado = objetoRobado
		this.mapamundi = mapamundi
		this.expedientes = expedientes
	}

	@JsonIgnore
	def Mapamundi getMapamundi() {
		this.mapamundi
	}
	
	@JsonIgnore
	def void setMapamundi(Mapamundi mapamundi) {
		this.mapamundi = mapamundi
	}
	
	@JsonIgnore
	def List<Pais> getRutaDeEscape() {
		this.rutaDeEscape
	}
	
	@JsonIgnore
	def void setRutaDeEscape(List<Pais> rutaDeEscape) {
		this.rutaDeEscape = rutaDeEscape
	}
	
	/* 
	 * Inicializa un caso con villano, inicio, y ruta de escape (Todos aleatorios) 
	 * Ademas, pone en cada lugar el tipo de ocupante correspondiente 
	 */
	def vincular() {
		responsable = randomVillano
		this.setearAMapamundi
		setearInicioRandom
		crearRutaDeEscape
		setearOcupantes	
	}
	
	def setearInicio(Pais pais) {
		this.paisDelRobo = pais
		this.rutaDeEscape += pais
	}
	
	def setearInicioRandom() {
		val randomIndex = mapamundi.paises.calculeRandomIndex
		val paisInicio = mapamundi.paises.get(randomIndex)
		setearInicio(paisInicio)
	}
	
	def Villano randomVillano() {
		expedientes.villanos.get((Math.random*(expedientes.villanos.size)).intValue)
	}
	
	
	def siguiente(Pais pais) {
		val indexActual = rutaDeEscape.indexOf(pais)
		rutaDeEscape.get(indexActual + 1)		
	}
	
	// Suplanta los "paises huecos" del caso, con los paises verdaderos del mapamundi
	def rellenarDatosPaisesDeEscape() {
		paisDelRobo = mapamundi.buscarPais(paisDelRobo.nombre)
		rutaDeEscape.forEach[p | 
			val pReal = mapamundi.buscarPais(p.nombre) 
			val pIndex = rutaDeEscape.indexOf(p)
			rutaDeEscape.set(pIndex, pReal)
		]
	}
	

	def setearOcupantes() {
		ultimoPais.setearVillano
		paisesConPistas.forEach[p | p.setearInformantes]
		paisesAjenosAlCaso.forEach[p | p.setearCuidadores]
	}
	
	def setearAMapamundi() {
		mapamundi.caso = this	
	}
	
	def	paisesAjenosAlCaso() {
		mapamundi.paises.filter[p | 
			!rutaDeEscape.contains(p)
		]	
	}

	def paisesConPistas() {
		rutaDeEscape.take(rutaDeEscape.size - 1).toList
	}
	
	def ultimoPais() {
		rutaDeEscape.last
	}

	def agregarPais(String nombre) {
		val pais = mapamundi.buscarPais(nombre)
		if (!rutaDeEscape.empty) pais.agregarConexion(ultimoPais)
		rutaDeEscape += pais
	}
	
	def nuevoPais(String nombre) {
		new Pais(nombre) => [ mapamundi = mapamundi ]
	}
	
	def crearRutaDeEscape() {
		var tamRuta = 7
		do {
			var random = mapamundi.paises.calculeRandomIndex
			var next = mapamundi.paises.get(random) 
				if(!rutaDeEscape.contains(next) && next!=ultimoPais) {
					ultimoPais.agregarConexion(next);
					rutaDeEscape += next
					tamRuta--
				}
		} while (tamRuta > 0)
	}
	
//	def crearRutaDeEscape() {
//		var tamRuta = 7
//		do {
//			val randomNext = ultimoPais.conexiones.calculeRandomIndex
//			val next = ultimoPais.conexiones.get(randomNext)
//			if(!rutaDeEscape.contains(next)) {
//				rutaDeEscape += next
//				tamRuta--
//			}
//		// hasta que hayan 7 paises o el ultimo pais no tenga conexiones validas para la ruta de escape
//		} while (tamRuta > 0 || !rutaDeEscape.containsAll(ultimoPais.conexiones)) 
//	}
	
}